package com.producteev4j.services.version0;

import com.producteev4j.exceptions.ProducteevException;
import com.producteev4j.exceptions.ProducteevServiceException;
import com.producteev4j.exceptions.ProducteevSignatureException;
import com.producteev4j.model.json.time.TimeWrapperImpl;
import com.producteev4j.model.request.ProducteevDateUtil;
import com.producteev4j.model.request.ProducteevGetRequest;
import com.producteev4j.model.request.ProducteevRequest;
import com.producteev4j.model.response.*;
import com.producteev4j.services.ProducteevService;
import com.producteev4j.transport.ProducteevTransport;

import java.text.ParseException;
import java.util.Date;
import java.util.List;

/**
 * Created by IntelliJ IDEA.
 * User: jcarrey
 * Date: 14/05/11
 * TimeImpl: 13:30
 * To change this template use File | Settings | File Templates.
 */
public class ProducteevServiceV0 implements ProducteevService {


    private ProducteevTransport transport;

    public static final String PRODUCTEEV_API_ENDPOINT = "https://api.producteev.com";


    private static final String TIME_CONTEXT_PATH = "";
    private static final String TIME_VIEW_SERVICE = "/time.json";

    // Services endpoints
    private static final String GET_TIME_SERVICE = PRODUCTEEV_API_ENDPOINT + TIME_CONTEXT_PATH + TIME_VIEW_SERVICE;

    private ProducteevUserService userService;
    private ProducteevTaskService taskService;
    private ProducteevLabelService labelService;
    private ProducteevActivityService activityService;
    private ProducteevDashboardService dashboardService;

    public ProducteevServiceV0() {
        userService = new ProducteevUserServiceV0Impl();
        taskService = new ProducteevTaskServiceV0Impl();
        labelService = new ProducteevLabelServiceV0Impl();
        activityService = new ProducteevActivityServiceV0Impl();
        dashboardService = new ProducteevDashboardServiceV0Impl();
    }


    public void setTransport(ProducteevTransport transport) {
        this.transport = transport;
    }

    public Date getTime() throws ProducteevException {
        ProducteevRequest getTimeRequest = new ProducteevGetRequest();
        getTimeRequest.setResponseClass(TimeWrapperImpl.class);
        getTimeRequest.setEndpoint(GET_TIME_SERVICE);

        try {
            return ProducteevDateUtil.parseDateRFC(
                    ProducteevValidator.assertNoError(
                            (TimeWrapperImpl) transport.process(getTimeRequest, null)).getTime().getValue()
            );
        } catch (ParseException e) {
            throw new ProducteevServiceException("Cannot parse date", e);
        }

    }


    /**
     * Log the current email user with the RAW password
     *
     * @param email    - Mandatory - the email of user
     * @param password - Mandatory - the password of user
     * @return - User information
     * @throws ProducteevSignatureException - Error signing message with MD5
     * @throws ProducteevServiceException   - On service error
     */
    public UserLogin userLogin(String email, String password) throws ProducteevException {
        return userService.userLogin(transport, email, password);
    }

    public UserLogin userFacebookLogin(long facebookId, String facebookOauthToken) throws ProducteevException {
        return userService.userLoginFacebook(transport, facebookId, facebookOauthToken);
    }

    @Override
    public User setDefaultDashboard(String userToken, long idDashboard) throws ProducteevException {
        return userService.setDefaultDashboard(transport, userToken, idDashboard);
    }

    public List<? extends UserWrapper> getColleagues(String userToken) throws ProducteevException {
        return userService.getColleagues(transport, userToken);
    }

    @Override
    public User signupUser(String firstName, String lastName, String password, String email, String timeZone, Long fbuid) throws ProducteevException {
        return userService.signupUser(transport, firstName, lastName, password, email, timeZone, fbuid);
    }

    @Override
    public User setSortByType(String userToken, int sortByType) throws ProducteevException {
        return userService.setSortByType(transport, userToken, sortByType);
    }


    /**
     * Get the user info
     *
     * @param userToken  - User login token ( Mandatory )
     * @param idCollegue - (Optional) An user can only see information about another user who is on the same dashboard
     * @return User information
     */
    public User getUser(String userToken, String idCollegue) throws ProducteevException {
        return userService.getUser(transport, userToken, idCollegue);
    }


/*
    public void afterPropertiesSet() throws ProducteevConfigException {
        if (transport == null) {
            throw new ProducteevConfigException("No transport configured for service : " + getClass());
        }
    }
*/

    public Task createTask(String userToken, String title, Long idResponsible,
                           Long idDashboard, String deadline, Integer allDay, Integer reminder, Integer status,
                           Integer star, String repeatinginterval, Integer repeatingValue, Long[] idLabel) throws ProducteevException {
        return taskService.createTask(transport, userToken, title, idResponsible, idDashboard, deadline, allDay, reminder, status, star, repeatinginterval, repeatingValue, idLabel);
    }

    /**
     * Get tasks full list
     *
     * @param userToken
     * @param since     - NULL a MUST ! Not working - (Optional) - Task since this date
     * @return
     * @throws ProducteevException
     */
    @Override
    public List<? extends TaskWrapper> getTasks(String userToken, Date since, Long dashboard, Integer page) throws ProducteevException {
        return taskService.getTasks(transport, userToken, since, dashboard, page);
    }

    /**
     * Get task by Id
     *
     * @param userToken
     * @param taskId
     * @return
     * @throws ProducteevException
     */
    @Override
    public Task getTask(String userToken, long taskId) throws ProducteevException {
        return taskService.getTask(transport, userToken, taskId);
    }

    @Override
    public List<? extends UserWrapper> getTaskAccessControlList(String userToken, long idTask) throws ProducteevException {
        return taskService.getTaskAccessControlList(transport, userToken, idTask);
    }

    @Override
    public boolean deleteTask(String userToken, long idTask) throws ProducteevException {
        return taskService.deleteTask(transport, userToken, idTask);
    }

    @Override
    public Task unsetTaskRepeating(String userToken, long idTask) throws ProducteevException {
        return taskService.unsetTaskRepeating(transport, userToken, idTask);
    }

    @Override
    public Task setTaskRepeating(String userToken, long idTask, String repeatingInterval, Integer repeatingValue) throws ProducteevException {
        return taskService.setTaskRepeating(transport, userToken, idTask, repeatingInterval, repeatingValue);
    }

    @Override
    public Task setTaskReminder(String userToken, long idTask, int idReminder) throws ProducteevException {
        return taskService.setTaskReminder(transport, userToken, idTask, idReminder);
    }

    @Override
    public Task unsetTaskDeadline(String userToken, long idTask) throws ProducteevException {
        return taskService.unsetTaskDeadline(transport, userToken, idTask);
    }

    @Override
    public Task setTaskDeadline(String userToken, long idTask, Date deadline, boolean allDay) throws ProducteevException {
        return taskService.setTaskDeadline(transport, userToken, idTask, deadline, allDay);
    }

    @Override
    public Task unsetTaskResponsible(String userToken, long idTask, long idResponsible) throws ProducteevException {
        return taskService.unsetTaskResponsible(transport, userToken, idTask, idResponsible);
    }

    @Override
    public Task setTaskResponsible(String userToken, long idTask, long idResponsible) throws ProducteevException {
        return taskService.setTaskResponsible(transport, userToken, idTask, idResponsible);
    }

    @Override
    public Task setTaskStars(String userToken, long idTask, int stars) throws ProducteevException {
        return taskService.setTaskStars(transport, userToken, idTask, stars);
    }

    @Override
    public Task setTaskTitle(String userToken, long idTask, String title) throws ProducteevException {
        return taskService.setTaskTitle(transport, userToken, idTask, title);
    }

    @Override
    public Task setTaskStatus(String userToken, long idTask, int status) throws ProducteevException {
        return taskService.setTaskStatus(transport, userToken, idTask, status);
    }

    @Override
    public List<? extends TaskWrapper> getArchivedTasks(String userToken, Date since, Long dashboard, Integer page) throws ProducteevException {
        return taskService.getArchivedTasks(transport, userToken, since, dashboard, page);
    }

    @Override
    public List<? extends TaskWrapper> getMyTasks(String userToken, Date since, Long dashboard, Integer page) throws ProducteevException {
        return taskService.getMyTasks(transport, userToken, since, dashboard, page);
    }

    @Override
    public List<? extends TaskWrapper> getMyTeamTasks(String userToken, Date since, Long dashboard, Integer page) throws ProducteevException {
        return taskService.getMyTeamTasks(transport, userToken, since, dashboard, page);
    }

    @Override
    public List<? extends LabelWrapper> getTaskLabels(String userToken, long idTask) throws ProducteevException {
        return taskService.getTaskLabels(transport, userToken, idTask);
    }

    @Override
    public Task changeTaskLabels(String userToken, long idTask, Long[] idLabels) throws ProducteevException {
        return taskService.changeTaskLabels(transport, userToken, idTask, idLabels);
    }

    /*
    @Override
    public List<? extends UserWrapper> getTaskUserList(String userToken, long idTask) throws ProducteevException {
        return taskService.getTaskUserList(transport, userToken, idTask);
    }
    */
    @Override
    public Task setTaskWorkspace(String userToken, long idTask, long idDashboard) throws ProducteevException {
        return taskService.setTaskWorkspace(transport, userToken, idTask, idDashboard);
    }

    @Override
    public Note getNote(String userToken, long idNote) throws ProducteevException {
        return taskService.getNote(transport, userToken, idNote);
    }

    @Override
    public List<? extends NoteWrapper> getTaskNotes(String userToken, long idTask, Date since) throws ProducteevException {
        return taskService.getTaskNotes(transport, userToken, idTask, since);
    }

    @Override
    public List<? extends ActivityWrapper> getTaskActivity(String userToken, long idTask, Integer page) throws ProducteevException {
        return taskService.getTaskActivity(transport, userToken, idTask, page);
    }

    @Override
    public Activity getActivity(String userToken, long idActivity) throws ProducteevException {
        return taskService.getActivity(transport, userToken, idActivity);
    }

    @Override
    public boolean deleteNote(String userToken, long idNote) throws ProducteevException {
        return taskService.deleteNote(transport, userToken, idNote);
    }

    @Override
    public Note createNote(String userToken, long idTask, String message) throws ProducteevException {
        return taskService.createNote(transport, userToken, idTask, message);
    }

    @Override
    public Label getLabel(String userToken, long idLabel) throws ProducteevException {
        return labelService.getLabel(transport, userToken, idLabel);
    }

    @Override
    public List<? extends LabelWrapper> getLabels(String userToken, long idDashboard, Date since, Integer page) throws ProducteevException {
        return labelService.getLabels(transport, userToken, idDashboard, since, page);
    }

    @Override
    public Label createLabel(String userToken, long idDashboard, String title) throws ProducteevException {
        return labelService.createLabel(transport, userToken, idDashboard, title);
    }

    @Override
    public boolean deleteLabel(String userToken, long idLabel) throws ProducteevException {
        return labelService.deleteLabel(transport, userToken, idLabel);
    }

    @Override
    public List<? extends TaskWrapper> getTasksWithLabel(String userToken, long idLabel, Integer page) throws ProducteevException {
        return labelService.getTasksWithLabel(transport, userToken, idLabel, page);
    }

    @Override
    public Label setLabelTitle(String userToken, long idLabel, String title) throws ProducteevException {
        return labelService.setLabelTitle(transport, userToken, idLabel, title);
    }

    @Override
    public List<? extends ActivityWrapper> getActivities(String userToken, Long idDashboard, Long lastId, Long page) throws ProducteevException {
        return activityService.getActivities(transport, userToken, idDashboard, lastId, page);
    }

    @Override
    public List<? extends ActivityWrapper> getNotifications(String userToken, Long idDashboard, Long lastId, Long page) throws ProducteevException {
        return activityService.getNotifications(transport, userToken, idDashboard, lastId, page);
    }

    @Override
    public List<? extends ActivityWrapper> setNotificationRead(String userToken, long idDashboard, long lastId) throws ProducteevException {
        return activityService.setNotificationRead(transport, userToken, idDashboard, lastId);
    }

    @Override
    public DashBoard createDashboard(String userToken, String title) throws ProducteevException {
        return dashboardService.createDashboard(transport, userToken, title);
    }

    @Override
    public DashBoard getDashboard(String userToken, long idDashboard) throws ProducteevException {
        return dashboardService.getDashboard(transport, userToken, idDashboard);
    }

    @Override
    public List<? extends DashBoardWrapper> getDashboards(String userToken, Date since, Integer page) throws ProducteevException {
        return dashboardService.getDashboards(transport, userToken, since, page);
    }

    @Override
    public List<? extends UserWrapper> getDashboardAccess(String userToken, long idDashboard) throws ProducteevException {
        return dashboardService.getDashboardAccess(transport, userToken, idDashboard);
    }

    @Override
    public DashBoard leaveOrDelegateDashboard(String userToken, long idDashboard, Long idUser, Long idDelegate) throws ProducteevException {
        return dashboardService.leaveOrDelegateDashboard(transport, userToken, idDashboard, idUser, idDelegate);
    }

    @Override
    public DashBoard setTitle(String userToken, long idDashboard, String title) throws ProducteevException {
        return dashboardService.setTitle(transport, userToken, idDashboard, title);
    }

    //@Override
    public DashBoard setSmartLabels(String userToken, long idDashboard, int value) throws ProducteevException {
        return dashboardService.setSmartLabels(transport, userToken, idDashboard, value);
    }

    @Override
    public boolean deleteDashboard(String userToken, long idDashboard) throws ProducteevException {
        return dashboardService.deleteDashboard(transport, userToken, idDashboard);
    }

    @Override
    public List<? extends TaskWrapper> getDashboardTasks(String userToken, long idDashboard, Date since, Integer page) throws ProducteevException {
        return dashboardService.getDashboardTasks(transport, userToken, idDashboard, since, page);
    }

    @Override
    public DashBoard confirmInvitation(String userToken, long idDashboard) throws ProducteevException {
        return dashboardService.confirmInvitation(transport, userToken, idDashboard);
    }

    @Override
    public DashBoard refuseInvitation(String userToken, long idDashboard) throws ProducteevException {
        return dashboardService.refuseInvitation(transport, userToken, idDashboard);
    }

    @Override
    public DashBoard inviteUserById(String userToken, long idDashboard, long idUserTo) throws ProducteevException {
        return dashboardService.inviteUserById(transport, userToken, idDashboard, idUserTo);
    }

    @Override
    public DashBoard inviteUserByEmail(String userToken, long idDashboard, String email) throws ProducteevException {
        return dashboardService.inviteUserByEmail(transport, userToken, idDashboard, email);
    }

    @Override
    public List<? extends DashBoardWrapper> getDashboardsToUpgrade(String userToken) throws ProducteevException {
        return dashboardService.getDashboardsToUpgrade(transport, userToken);
    }

    @Override
    public boolean needsUpgrade(String userToken, long idDashboard) throws ProducteevException {
        return dashboardService.needsUpgrade(transport, userToken, idDashboard);
    }


}
